package sg.edu.nus.iss.vmcs.customer;

import sg.edu.nus.iss.vmcs.store.Store;
import sg.edu.nus.iss.vmcs.store.StoreItem;
import sg.edu.nus.iss.vmcs.util.VMCSException;

/*
 * Copyright 2003 ISS.
 * The contents contained in this document may not be reproduced in any
 * form or by any means, without the written permission of ISS, other
 * than for the purpose for which it has been supplied.
 *
 */

/**
 * This control object is for handling the dispense product use case.
 * 
 * @version 1.0 11 Oct 2008
 * @author Toh Kim Huat
 */

public class DispenseController {
	
	private static final String LABEL_NO_CAN = "NO CAN";

	/**
	 * Transaction controller which created this object
	 */
	private TransactionController transactionController;
	
	/**
	 * This constructor creates an instance of the object
	 * 
	 * @param transactionController
	 *            Transaction Controller controlling this object
	 */
	public DispenseController(TransactionController transactionController) {
		this.transactionController = transactionController;
	}
	
	/**
	 * This operation will be used to activate/deactivate (as indicated through
	 * a parameter) the Product Selection Box so that transactions can continue or
	 * will be disallowed.
	 * 
	 * @param allow
	 *            Boolean to indicate whether selections are allowed
	 */
	public void allowSelection(boolean allow) {
		this.transactionController.getCustomerPanel().getProductSelectionBox()
				.setActive(allow);
	}
	
	/**
	 * This operation will be used to dispense a product. It will:
	 * 
	 * 1. Instruct the Products Store to dispense the product. It will also instruct
	 * the Can Collection Box to display a can shape.
	 * 2. Instruct the Store Controller to update the Products Store Display on
	 * the Machinery Simulator Panel.
	 * 3. In the case of fault detection, it will send a "fault detected" 
	 * response to the Transaction Controller.
	 * 
	 * @param selectedBrand Index of the selected brand
	 * @return TRUE if product is dispensed
	 */
	public boolean dispenseProduct(int selectedBrand) {
		try {
			this.transactionController.getMainController()
					.getMachineryController().dispenseProduct(selectedBrand);
//			if(selectedBrand == 0){
//				throw new VMCSException();
//			}
			
		} catch (VMCSException e) {
			this.transactionController
					.terminateFault(TransactionController.FAULT_TYPE_DISPENSE);
			return false;
		}
		String brandName = this.transactionController.getMainController()
				.getStoreController().getStoreItem(Store.PRODUCT, selectedBrand)
				.getContent().getName();
		this.transactionController.getCustomerPanel().getCanCollectionBox()
				.setValue(brandName);
		updateProductSelection(selectedBrand);
		return true;
	}

	/**
	 * This operation will be used to instruct the Can Collection Box to remove
	 * the products shape or product brand name from being displayed.
	 */
	public void resetCan() {
		this.transactionController.getCustomerPanel().getCanCollectionBox()
				.setValue(LABEL_NO_CAN);
	}
	
	/**
	 * This operation updates the whole Product Selection Box with current names,
	 * stocks and prices
	 */
	public void updateProductPanel() {
        int storeSize = transactionController.getMainController()
				.getStoreController().getStoreSize(Store.PRODUCT);
		for (int i = 0; i < storeSize; i++) {
			updateProductSelection(i);
		}
	}
	
	/**
	 * This operation is used to display the latest stock and price information
	 * on the Product Selection Box
	 * 
	 * @param index
	 *            Index of the product
	 */
	public void updateProductSelection(int index) {

		Store store = transactionController.getMainController()
				.getStoreController().getStore(Store.PRODUCT);
		StoreItem storeItem = store.getStoreItem(index);
		ProductSelectionBox productSelectionBox = transactionController
				.getCustomerPanel().getProductSelectionBox();

		productSelectionBox.update(index, storeItem);

	}

}
